package com.sec.android.app.myfiles.feature;

import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;

import com.sec.android.app.myfiles.feature.mousekeyboard.MouseKeyboardImp;
import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.fragment.filelist.OnItemChangedListener;
import com.sec.android.app.myfiles.info.AppFeatures;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.navigation.NavigationInfo;
import com.sec.android.app.myfiles.navigation.NavigationManager;

import java.util.ArrayList;

public class MouseKeyboardMgr {

    private static MouseKeyboardImp sMouseKeyboardImp = new MouseKeyboardImp();


    private MouseKeyboardMgr() {
    }

    public static boolean isCtrlCopied() {
        return sMouseKeyboardImp.isCtrlCopied();
    }

    public static void setCtrlCopy(boolean isCopy) {
        sMouseKeyboardImp.setCtrlCopy(isCopy);
        notifyItemUpdated();
    }

    public static void setCtrlMove(boolean isMoved) {
        sMouseKeyboardImp.setCtrlMove(isMoved);
        notifyItemUpdated();
    }

    public static boolean isCtrlMoved() {
        return sMouseKeyboardImp.isCtrlMoved();
    }

    public static boolean isShiftPressed() {
        return sMouseKeyboardImp.isShiftPressed();
    }

    public static boolean isCtrlPressed() {
        return sMouseKeyboardImp.isCtrlPressed();
    }

    public static void setCtrlPress(boolean ctrlPress) {
        sMouseKeyboardImp.setCtrlPress(ctrlPress);
    }

    public static void setShftPress(boolean shiftPress) {
        sMouseKeyboardImp.setShiftPress(shiftPress);
    }

    public static void setFocusedListIndexForMouse(int startPos) {
        sMouseKeyboardImp.setFocusedListIndex(startPos);
    }

    public static ArrayList<FileRecord> getSelectedFile() {
        return sMouseKeyboardImp.getSelectedFile();
    }

    public static void onShiftMouseClick(AbsMyFilesFragment fragment, AbsListView listViewImp, int lastPostion) {
        sMouseKeyboardImp.onShiftMouseClick(fragment, listViewImp, lastPostion);
        notifyItemUpdated();
    }

    public static void onCtrlMouseClick(AbsMyFilesFragment fragment, AbsListView listViewImp, int position) {
        sMouseKeyboardImp.onCtrlMouseClick(fragment, listViewImp, position);
        notifyItemUpdated();
    }

    public static void onCtrlMouseWheel(MotionEvent event, AbsMyFilesFragment fragment, FileRecord record) {
        sMouseKeyboardImp.onCtrlMouseWheel(event, fragment, record);
    }

    public static void onCtrlV(AbsMyFilesFragment fragment, FileRecord curRecord) {
        sMouseKeyboardImp.onCtrlV(fragment, curRecord);
    }

    public static void onCtrlC(AbsMyFilesFragment fragment, FileRecord record) {
        sMouseKeyboardImp.onCtrlC(fragment, record);
        notifyItemUpdated();
    }

    public static void onCtrlX(AbsMyFilesFragment fragment, FileRecord record) {
        sMouseKeyboardImp.onCtrlX(fragment, record);
        notifyItemUpdated();
    }

    public static void onCancel() {
        if (isCtrlCopied()) {
            setCtrlCopy(false);
        }
        if (isCtrlMoved()) {
            setCtrlMove(false);
        }
    }

    private static boolean onCtrlPressed(int keyCode, KeyEvent event, AbsMyFilesFragment fragment, FileRecord record, int position, AbsListView listViewImp) {
        boolean isCtrlKeyPressed = false;
        if (event.isCtrlPressed()) {
            setCtrlPress(true);
            switch (keyCode) {
                case KeyEvent.KEYCODE_C:
                    onCtrlC(fragment, record);
                    break;
                case KeyEvent.KEYCODE_V:
                    if (record.getStorageType() != FileRecord.StorageType.Category) {
                        if (record.getStorageType() != FileRecord.StorageType.FolderTree) {
                            FileRecord curRecord = fragment.getNavigationInfo().getCurRecord();
                            sMouseKeyboardImp.onCtrlV(fragment, curRecord);
                        } else {
                            sMouseKeyboardImp.onCtrlV(fragment, record);
                        }
                    }
                    break;
                case KeyEvent.KEYCODE_X:
                    onCtrlX(fragment, record);
                    break;
                case KeyEvent.KEYCODE_A:
                    sMouseKeyboardImp.onCtrlA(fragment);
                    break;
                case KeyEvent.KEYCODE_D:
                    sMouseKeyboardImp.onCtrlD(fragment, record, listViewImp, position);
                    break;
                case KeyEvent.KEYCODE_ENTER:
                    sMouseKeyboardImp.onEnter(fragment, record);
                    break;
            }
            isCtrlKeyPressed = true;
        }
        return isCtrlKeyPressed;
    }

    private static boolean onShiftPressed(int keyCode, KeyEvent event, AbsMyFilesFragment fragment, FileRecord record, int position, AbsListView listViewImp) {
        boolean isShiftKeyPressed = false;
        if (event.isShiftPressed()) {
            setShftPress(true);
            switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    if (record.getStorageType() != FileRecord.StorageType.FolderTree) {
                        sMouseKeyboardImp.onShiftArrowDown(fragment, listViewImp, position);
                    }
                    break;
                case KeyEvent.KEYCODE_DPAD_UP:
                    if (record.getStorageType() != FileRecord.StorageType.FolderTree) {
                        sMouseKeyboardImp.onShiftArrowUp(fragment, listViewImp, position);
                    }
                    break;
            }
            isShiftKeyPressed = true;
        }
        return isShiftKeyPressed;
    }

    public static void onKeyEvent(int keyCode, KeyEvent event, AbsMyFilesFragment fragment, AbsListView listViewImp, FileRecord.StorageType storageType) {
        Log.d(MouseKeyboardMgr.class, "onKeyEvent - " + keyCode);
        boolean isShiftCtrlKeyPressed;
        int position = -1;

        FileRecord record = null;
        if (listViewImp != null) {
            position = listViewImp.getSelectedItemPosition();
            if (position > -1) {
                if (storageType == FileRecord.StorageType.Search) {
                    record = fragment.getFileRecord(position - 1);
                } else {
                    record = fragment.getFileRecord(position);
                }
            }
        }

        if (position > -1 && record != null) {
            if (isSupportKeyboradStorageType(record)) {
                isShiftCtrlKeyPressed = onShiftPressed(keyCode, event, fragment, record, position, listViewImp);
                if (!isShiftCtrlKeyPressed) {
                    isShiftCtrlKeyPressed = onCtrlPressed(keyCode, event, fragment, record, position, listViewImp);
                }
                if (!isShiftCtrlKeyPressed) {
                    if (keyCode == KeyEvent.KEYCODE_F2) {
                        sMouseKeyboardImp.onF2(fragment, listViewImp, record, position);
                    } else if (keyCode == KeyEvent.KEYCODE_DEL) {
                        sMouseKeyboardImp.onDel(fragment, listViewImp);
                    } else if (keyCode == KeyEvent.KEYCODE_ESCAPE) {
                        onCancel();
                    }
                }
            }
        } else {
            NavigationManager navigationMgr = NavigationManager.getInstance(fragment.getProcessId());
            if (navigationMgr != null) {
                NavigationInfo curInfo = navigationMgr.getCurInfo();
                if (curInfo != null) {
                    FileRecord curRecord = curInfo.getCurRecord();
                    if (isSupportKeyboradStorageType(curRecord)) {
                        if (event.isCtrlPressed()) {
                            setCtrlPress(true);
                            switch (keyCode) {
                                case KeyEvent.KEYCODE_C:
                                    onCtrlC(fragment, curRecord);
                                    break;
                                case KeyEvent.KEYCODE_X:
                                    onCtrlX(fragment, curRecord);
                                    break;
                                case KeyEvent.KEYCODE_V:
                                    onCtrlV(fragment, curRecord);
                                    break;
                                case KeyEvent.KEYCODE_D:
                                    sMouseKeyboardImp.onDel(fragment, listViewImp);
                                    break;
                                case KeyEvent.KEYCODE_A:
                                    sMouseKeyboardImp.onCtrlA(fragment);
                                    break;
                            }
                        }
                    }
                }
            }
        }
    }

    private static boolean isSupportKeyboradStorageType(FileRecord record) {
        boolean ret = false;
        if (record.getStorageType() == FileRecord.StorageType.Local || record.getStorageType() == FileRecord.StorageType.FolderTree
                || record.getStorageType() == FileRecord.StorageType.Search || record.getStorageType() == FileRecord.StorageType.Cloud
                || record.getStorageType() == FileRecord.StorageType.Category) {
            ret = true;
        }
        return ret;
    }

    public static void addOnItemChangedListener(OnItemChangedListener listener) {
        if (AppFeatures.isKnoxDesktopMode()) {
            sMouseKeyboardImp.addOnItemChangedListener(listener);
        }
    }

    public static void removeOnItemChangedListener(OnItemChangedListener listener) {
        if (AppFeatures.isKnoxDesktopMode()) {
            sMouseKeyboardImp.removeOnItemChangedListener(listener);
        }
    }

    public static void notifyItemUpdated() {
        sMouseKeyboardImp.notifyItemUpdated();
    }

    public static void setOnKeyListener(final AbsListView listView, final AbsMyFilesFragment fragment, final FileRecord.StorageType storageType) {
        if (!AppFeatures.isKnoxDesktopMode()) {
            return;
        }

        fragment.registerForContextMenu(listView);

        listView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                switch (event.getAction()) {
                    case KeyEvent.ACTION_DOWN:
                        MouseKeyboardMgr.onKeyEvent(keyCode, event, fragment, listView, storageType);
                        break;
                    case KeyEvent.ACTION_UP:
                        MouseKeyboardMgr.setShftPress(false);
                        MouseKeyboardMgr.setCtrlPress(false);
                        MouseKeyboardMgr.setFocusedListIndexForMouse(listView.getSelectedItemPosition());
                        break;
                }
                return false;
            }
        });

        listView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    if (!v.isFocused()) {
                        v.requestFocus();
                    }
                    if (event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
                        int x = (int) event.getX();
                        int y = (int) event.getY();
                        AbsListView listView = (AbsListView) v;
                        int clickPos = listView.pointToPosition(x, y);
                        fragment.setTouchPosition(clickPos);
                        v.showContextMenu(event.getX(), event.getY());
                    }
                }
                return false;
            }
        });
    }

    public static void setOnTouchListenerForEmptyView(final View emptyView, final AbsMyFilesFragment fragment) {
        if (!AppFeatures.isKnoxDesktopMode()) {
            return;
        }

        fragment.registerForContextMenu(emptyView);

        emptyView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN && event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
                    fragment.setTouchPosition(-1);
                    v.showContextMenu(event.getX(), event.getY());
                }
                return false;
            }
        });
    }
}
